import { moveDPForward, moveDP } from "@/utils/number";
let jSW = undefined;

export const getStatus = device => device?._info_pu?.onlinestatus;
export const isOnline = device => getStatus(device) === 1;
export const getDeviceId = device => device?._id_pu;
export const gpsOn = device => device?._arr_gps[0]?.m_is_open;
export default class JSW {
  session = null;
  confManager = null;
  currentConf = null;
  currentConfInfo = {};
  inited = false;
  config = {
    sessionServer: "127.0.0.1",
    sessionPort: "9701",
    serverUrl: "",
    serverCallType: 0,
    user: "admin",
    password: "123456"
  };
  constructor(config = {}) {
    if (!window.jSW) {
      throw new Error("no JSW!");
    }
    jSW = window.jSW;
  }
  init(config = {}) {
    Object.assign(this.config, config);
    return this.swInit()
      .then(() => this.SWSession())
      .then(() => this.login());
  }
  swInit(config = {}) {
    return new Promise((resolve, reject) => {
      if (this.inited) {
        resolve();
        return;
      }
      if (!jSW) {
        reject();
        return;
      }
      jSW.swInit({
        url: this.config?.serverUrl,
        callType: this.config?.serverCallType,
        ...config,
        oninit: code => {
          if (code !== jSW.RcCode.RC_CODE_S_OK) {
            this.inited = true;
            reject(code);
            return;
          }
          resolve();
        }
      });
    });
  }

  SWSession() {
    console.log(this);
    const server = this.config.sessionServer;
    const port = this.config.sessionPort;
    return new Promise((resolve, reject) => {
      if (!jSW) {
        reject();
        return;
      }
      if (this.session) {
        resolve(this.session);
        return;
      }
      new jSW.SWSession({
        server,
        port,
        onclose: (...params) => {
          reject(params);
        },
        onopen: sess => {
          this.session = sess;
          resolve(this.session);
        }
      });
    });
  }
  SWSessionDestroy() {
    this.session?.swDispose();
  }
  login() {
    const user = this.config.user;
    const password = this.config.password;
    return new Promise((resolve, reject) => {
      if (!this.session) {
        reject(new Error("no session"));
        return;
      }
      this.session.swAddCallBack("login", () => {
        resolve(this.session);
      });
      this.session.swLogin({ user, password });
    });
  }
  /**
   *
   * @param {*} param0
   *  @param {*} param0.iOnlineStatus 0:all 1:online 2:offline
   *  @param {*} param0.iTimeBegin seconds
   * @returns
   */
  deviceList({
    iOnlineStatus = 0,
    iTimeBegin = 0,
    iTimeEnd = 0,
    szIDOrName = "",
    szGroupID = ""
  }) {
    return new Promise((resolve, reject) => {
      if (!this.session) {
        reject();
        return;
      }
      this.session.swSearchPuList({
        iPosition: 0,
        iCount: 128,
        stFilter: {
          iOnlineStatus,
          iTimeBegin,
          iTimeEnd,
          szIDOrName,
          szGroupID
        },
        callback: (options, response, data) => {
          if (response.emms.code !== jSW.RcCode.RC_CODE_S_OK) {
            reject(response);
            return;
          }
          resolve(data);
        }
      });
    });
  }
  gpsFile(puid, startTime, endTime) {
    if (!this.session) return Promise.reject();
    return new Promise(resolve => {
      this.session.swSearchGpsV2({
        stSearchInfo: {
          iPostition: 0,
          iCount: 1024
        },
        szPuid: puid,
        iTimeBegin: startTime,
        iTimeEnd: endTime,
        callback: (options, response, data) => {
          console.log(data);
          resolve(data);
        }
      });
    });
  }
  gpsRecordFromFile(nruid, gpsPath) {
    if (!this.session) return Promise.reject();
    return new Promise(resolve => {
      this.session.swGetGpsRecordDataV2({
        szNruId: nruid,
        szFilePath: gpsPath,
        callback: (options, response, data) => {
          console.log(data);
          data.data.forEach(i => {
            i.lng = moveDPForward(i.long, 3);
            i.lat = moveDPForward(i.lat, 2);
          });

          resolve(data);
        },
        tag: null
      });
    });
  }
  getVideoChanel(puid) {
    const swpu = this.session.swGetPu(puid);
    return swpu.swGetChanel(0);
  }
  getGPSChanel(puid) {
    const swpu = this.session.swGetPu(puid);
    return swpu._arr_gps[0];
  }
  getGPSCoordinate(puid, callback, once = false) {
    const gpsSession = this.getGPSChanel(puid);
    gpsSession.swOpen({
      callback: (e, response) => {
        // console.log(e, response);
        const { gps } = response;
        if (gps) {
          if (once) gpsSession.swClose();
          //   console.log(`===${puid}====收到GPS信号===`);
          const { long, lat, height, angle, speed } = gps;
          //   console.log(`========${new Date()}=======`);
          //   console.log(gps);
          callback({
            position: {
              lng: moveDPForward(long, 3),
              lat: moveDPForward(lat, 2),
              height: height * 100,
              angle: angle * 1000,
              speed
            },
            deviceId: puid,
            gpsSession
          });
        }
      }
    });
  }
  closeGPS(puid) {
    const gpsSession = this.getGPSChanel(puid);
    gpsSession.swClose();
  }
  startStream(puid, div) {
    return new Promise(resolve => {
      this.getVideoChanel(puid).swOpenEx({
        // prototype: "hls",
        usews: true,
        // bovertcp: true,
        ismuti: true,
        callback: (options, response, dlghandle) => {
          resolve(dlghandle);
        },
        div
      });
    });
  }
  stopStream(puid, hdlg) {
    this.getVideoChanel(puid).swClose(hdlg);
  }
  startAudio(puid) {
    return new Promise((resolve, reject) => {
      this.getVideoChanel(puid).swOpenIntercom({
        isSendAudio: true,
        isRecvAudio: true,
        callback: (options, response) => {
          if (response.emms.code == jSW.RcCode.RC_CODE_S_OK) {
            resolve();
          } else {
            reject();
          }
        }
      });
    });
  }
  stopAudio(puid) {
    return new Promise((resolve, reject) => {
      this.getVideoChanel(puid).swCloseIntercom({
        callback: (options, response) => {
          resolve(response);
        }
      });
    });
  }
  initConf() {
    if (this.confManager) return Promise.resolve(this.confManager);
    this.confManager = this.session.swGetConfManager();
    return new Promise((res, rej) => {
      this.confManager.swInit({
        callback: e => {
          if (e === 0) {
            res(this.confManager);
            return;
          }
          rej(new Error("会议初始化失败！"));
        }
      });
    });
  }
  joinConf({ confId, msgCallback = () => {}, speakCallback = () => {} }) {
    if (!this.confManager) return Promise.reject(new Error("会议尚未初始化"));
    this.confManager.swRegConfWatch((_, event, message) => {
      switch (event) {
        case "notifyapplyforstartspeak":
        case "notifyapplyforendspeak":
          speakCallback(message);
          break;
        case "notifyimmsg":
          msgCallback(message);
      }
    });
    return new Promise((res, rej) => {
      this.currentConf = this.confManager.swGetConfByConfId(confId);
      this.currentConfInfo = this.currentConf.swGetConfInfo();
      this.currentConf.swGetParticularList({
        callback: (_, __, users) => {
          users.forEach(user => {
            if (user.isleave) {
              this.currentConf.swParticipatorReturn(user);
            }
          });
        }
      });
      this.currentConf.swConfStart({
        callback: (_, response) => {
          res();
        }
      });
    });
  }
  sendConfMsg(data) {
    if (!this.currentConf) return;
    this.currentConf.swConfIMSend({
      msgitems: [
        {
          iType: 1,
          data
        }
      ],
      callback: () => {}
    });
  }
}
